

/** 数据事件 */
export class DataControlEvent {

    /** 数据整体更新 */
    static UPDATE = 'update';

    /** 添加一个数据 */
    static ADD = 'add';

    /** 删除一个数据 */
    static REMOVE = 'remove';


    //-----------------------------------------------


    private static pool: DataControlEvent[] = [];

    /** 从对象池创建一个事件对象 */
    static create() {
        let inst = DataControlEvent.pool.pop();
        if (!inst) inst = new DataControlEvent();
        return inst;
    }


    //-----------------------------------------------


    /** 事件类型 */
    type: string;

    /** 上下文Index */
    index: number;


    /** 回收该事件对象以重用 */
    recycle() {
        this.index = this.type = undefined;
        DataControlEvent.pool.push(this);
    }

}



//----------------------------------------------------------------------



/** 数据控制器 */
export class DataControl<Data = any> extends cc.EventTarget {



    constructor(source: Data[] = []) {
        super();
        this.setData(source);
    }



    private _source: Data[];

    /** 数据源，一搬只用于读取,直接操作此数据不会派发任何事件更新 */
    public get source() {
        return this._source;
    }




    /** 
     * 设置新的数据源
     * @param data 新的数据
     */
    public setData(data: Data[]) {
        if (!data) return;
        this._source = data;
        this.emitEvent(DataControlEvent.UPDATE);
    }




    /** 
     * 添加一个数据到局部
     * @param data 添加的数据
     * @param index 添加的位置,如果为空则添加到最末
     */
    public addData(data: Data, index?: number) {
        if (!this.source || !data) return;
        if (index == undefined) {
            index = this.source.length;
        }
        this.source.splice(index, 0, data);
        this.emitEvent(DataControlEvent.ADD, index);
    }




    /**
     * 删除一个数据
     * @param index 位置
     */
    public removeIndex(index: number) {
        if (!this.source) return;
        let arr = this.source.splice(index, 1);
        if (arr && arr.length > 0) {
            this.emitEvent(DataControlEvent.REMOVE, index);
        }
    }




    /** 调度一个事件 */
    private emitEvent(type: string, index?: number) {
        let evt = DataControlEvent.create();
        evt.type = type;
        evt.index = index;
        this.emit(type, evt);
    }



}